package cn.ljy.uem.service.impl;

import cn.hutool.core.map.BiMap;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.ljy.authority.model.SysUser;
import cn.ljy.authority.service.SysUserService;
import cn.ljy.common.exception.model.MyExcelException;
import cn.ljy.common.exception.model.MyServiceException;
import cn.ljy.common.exception.model.base.MyRollBackException;
import cn.ljy.common.model.result.ExcelImportResult;
import cn.ljy.common.utils.table.ExcelExceptionMessage;
import cn.ljy.common.utils.table.MyHutoolCustomExcelUtil;
import cn.ljy.common.utils.table.MyTableUtil;
import cn.ljy.uem.dao.SchoolDepartmentMapper;
import cn.ljy.uem.dao.SchoolMajorGroupMapper;
import cn.ljy.uem.dao.SchoolMajorGroupTeacherMapper;
import cn.ljy.uem.dao.SchoolTeacherMapper;
import cn.ljy.uem.model.SchoolDepartment;
import cn.ljy.uem.model.SchoolMajorGroup;
import cn.ljy.uem.model.SchoolMajorGroupTeacher;
import cn.ljy.uem.model.SchoolTeacher;
import cn.ljy.uem.model.query.SchoolMajorGroupQuery;
import cn.ljy.uem.service.SchoolMajorGroupExcelService;
import cn.ljy.uem.service.SchoolMajorGroupService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.NotNull;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 要在一般业务类只上构建的
 */
@Service
@Validated
@Slf4j
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor= MyRollBackException.class)
public class ISchoolMajorGroupExcelService implements SchoolMajorGroupExcelService {
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SchoolMajorGroupMapper schoolMajorGroupMapper;
    @Autowired
    private SchoolDepartmentMapper schoolDepartmentMapper;
    @Autowired
    private SchoolTeacherMapper schoolTeacherMapper;
    @Autowired
    private SchoolMajorGroupTeacherMapper schoolMajorGroupTeacherMapper;
    private String sheetName="专业群列表";//要查找的账户子表

    //定义表格的行对象，用于处理表格中的bean
    @Data
    private class SchoolMajorGroupRow{
        private Integer id;
        private String name;//专业群名称
        private String departmentName;//部门名称
        private String teacherNames;//群主教师集合
//        private Integer teacherNumber;//教师数量
        private Integer sort;//排序
        private Date createTime;//创建时间
        private Date updateTime;//最后编辑时间
    }
    //表格标题栏和实体的映射,必须为有序map集合
    private final static HashMap SCHOOLMAJORGROUPBEAN_MAP = new LinkedHashMap<String, String>(){
        {
            put("id","专业群编号");
            put("name","专业群名称");
            put("departmentName","部门名称");
            put("teacherNames","群主");
//            put("teacherNumber","群主数量");
            put("sort","排序");
            put("createTime","创建时间");
            put("updateTime","最后编辑时间");
        }
    };

    /**
     * 将user对象转换为要显示的表格行记录
     * @param schoolMajorGroup 应该是从数据库里面读取出来的对象。如果是新建对象，应该包含必须的属性（sex、status）
     * @param isTemplate 是否是模板。
     * @return
     */
    private SchoolMajorGroupRow convertSchoolMajorGroupToExcelRow(SchoolMajorGroup schoolMajorGroup,boolean isTemplate){
        SchoolMajorGroupRow row=null;
        if(schoolMajorGroup!=null){
            //定义行记录对象
            row=new SchoolMajorGroupRow();
            //属性拷贝,会将相同属性的值拷贝给新对象
            BeanUtils.copyProperties(schoolMajorGroup, row);
            //设置角色列表
            //设置角色列表下拉框。因为角色可以有多个，暂时不进行设置
            //writer.addSelect(5,1,nameZhs.toArray(new String[nameZhs.size()]));
            if(isTemplate){//如果是示例
                List<String> nameZhs=schoolTeacherMapper.getAllNames();//查找数据库所有中文角色名
                if(nameZhs.size()==1){//如果数据库只有一个角色
                    row.setTeacherNames(nameZhs.get(0));
                }else if(nameZhs.size()>1){//如果数据库有多个角色，则显示多个角色的示例，例如：超级管理员|普通管理员
                    row.setTeacherNames(nameZhs.get(0)+"|"+nameZhs.get(1));
                }
            } else{//如果展示记录数
                Set<SchoolTeacher> teachersSet=schoolMajorGroup.getTeachers();//获取该账户拥有的角色集合
                if(teachersSet!=null&&teachersSet.size()>0){//如果用户的角色集合存在，说明不是手动创建的对象，即非示例行
                    SchoolTeacher[] teachersArray=teachersSet.toArray(new SchoolTeacher[teachersSet.size()]);//转换为数组
                    StringBuilder teacherNameString=new StringBuilder();
                    //将群主集合转换为字符串形式在单元格显示，例如：“超级管理员|普通管理员”
                    for(int i=0;i<teachersArray.length;i++){
                        SchoolTeacher schoolTeacher=teachersArray[i];
                        teacherNameString.append(schoolTeacher.getName());
                        if(i!=teachersArray.length-1){
                            teacherNameString.append("|");
                        }
                    }
                    row.setTeacherNames(teacherNameString.toString());
                }
            }
            if(isTemplate) {//如果是示例
                //从数据库读取所有部门中文名
                List<String> departmentNames=schoolDepartmentMapper.getAllNames();
                if(departmentNames.size()>0){//默认选择的部门
                    row.setDepartmentName(departmentNames.get(0));
                }
            }else{
                //设置专业群信息
                if(schoolMajorGroup.getDepartmentId()!=null){//如果专业群存在
                    SchoolDepartment schoolDepartment = schoolDepartmentMapper.findById(schoolMajorGroup.getDepartmentId());
                    row.setDepartmentName(schoolDepartment.getName());
                }
            }
//            row.setTeacherNumber(schoolMajorGroupTeacherMapper.countAllTeacherByMajorGroupId(schoolMajorGroup.getId()));
        }
        return row;
    }
    
    @Override
    public ExcelWriter exportExcel(boolean isTemplate,SchoolMajorGroupQuery schoolMajorGroupQuery) {
        //通过工具类创建writer
        ExcelWriter writer = ExcelUtil.getWriter(true);
        //设置表格全局样式
        MyHutoolCustomExcelUtil.setBaseGlobalStyle(writer);
        //实现第一个sheet内容
        this.writeExportMajorGroupSheet(writer,isTemplate,schoolMajorGroupQuery);
        //添加第二个sheet:角色表
        this.writeExportTeacherSheet(writer);
        //添加第三个sheet:部门表
        this.writeExportDepartmentSheet(writer);
        return writer;
    }

    /**
     * 输出专业群列表sheet，默认是第一个sheet
     * 说明：
     * 1.如果是模板，则输出标题栏加示例；
     * 2.如果不是模板，则根据查询条件输出所有记录
     * @param writer
     * @param isTemplate 是否是模板
     * @param schoolMajorGroupQuery 查询条件
     */
    private void writeExportMajorGroupSheet(ExcelWriter writer, boolean isTemplate, SchoolMajorGroupQuery schoolMajorGroupQuery){
        // 定义专业群记录数集合
        List<SchoolMajorGroupRow> rows=new ArrayList<>();
        //自定义账户对象对应的标题别名,因为是LinkedHashMap，此处的keyset返回的是有序的。
//        Set<Map.Entry<String, String>> entryseSet=SYSUSERBEAN_MAP.entrySet();
//        for(Map.Entry<String, String> entry:entryseSet){
//            //自定义账户对象对应的标题别名
//            writer.addHeaderAlias(entry.getKey(),entry.getValue());
//        }
        //步骤一：重命名当前工作表名称。
        writer.renameSheet(sheetName);
        //步骤二：设置列宽
        //获取set集合，因为是LinkedHashMap集合，因此转换过来的是有序的set集合
        Set<String> keySet=SCHOOLMAJORGROUPBEAN_MAP.keySet();
        //转为list集合,用于在后面能够根据键值获取所在的列索引（避免直接操作列索引导致的灵活性不足）
        List<String> keyList=new ArrayList<String>(keySet);
        writer.setColumnWidth(keyList.indexOf("name"),20);
        //设置部门状态列宽
        writer.setColumnWidth(keyList.indexOf("departmentName"),30);
        //设置群主状态列宽
        writer.setColumnWidth(keyList.indexOf("teacherNames"),50);
        //设置群主数量列宽
//        writer.setColumnWidth(keyList.indexOf("teacherNumber"),20);
        //设置排序集合列宽
        writer.setColumnWidth(keyList.indexOf("sort"),30);

        writer.setColumnWidth(keyList.indexOf("createTime"),30);
        writer.setColumnWidth(keyList.indexOf("updateTime"),30);
        //步骤三：设置标题行的别名Map，以便直接通过Model对象生成表格数据，并且能够在model对象有数据时自动生成标题
        writer.setHeaderAlias(SCHOOLMAJORGROUPBEAN_MAP);
        //步骤四：添加数据行
        //从数据库读取所有部门中文名
        List<String> departmentNames=schoolDepartmentMapper.getAllNames();
        List<String> teacherNames=schoolTeacherMapper.getAllNames();

        if(isTemplate){//如果是模板，则在数据行添加示例数据
            //定义示例数据
            SchoolMajorGroup schoolMajorGroup=new SchoolMajorGroup();
            schoolMajorGroup.setName("大数据技术与应用专业群");
            schoolMajorGroup.setDepartmentId(1);
            Integer [] i=new Integer[1];
            Long[] num = new Long[1];;
            num[0]=1L;
//            i[0]=405;
            schoolMajorGroup.setTeacherIds(num);
//            schoolMajorGroup.setTeacherNumber(0);
            schoolMajorGroup.setSort(100);
            //定义行记录对象,并将对象转换过来
            SchoolMajorGroupRow row=this.convertSchoolMajorGroupToExcelRow(schoolMajorGroup,true);
            //将记录添加到集合
            rows.add(row);
        }else{//如果不是模板，则在数据行添加数据行记录
            List<SchoolMajorGroup> schoolMajorGroups = schoolMajorGroupMapper.findAll(schoolMajorGroupQuery);
            for(int i=0;i<schoolMajorGroups.size();i++){
                SchoolMajorGroup schoolMajorGroup=schoolMajorGroups.get(i);
                //定义行记录对象,并将对象转换过来
                SchoolMajorGroupRow row=this.convertSchoolMajorGroupToExcelRow(schoolMajorGroup,false);
                //将记录添加到集合
                rows.add(row);
            }
        }
        //步骤五：一次性写出内容，使用默认样式，强制输出标题。如果没有额外自定义样式，Hutool工具会自动生成统一的样式。但是如果使用了自定义样式这里就不会变化
        writer.write(rows, true);
        //步骤六：针对特殊单元格进行处理，包括值和特殊样式的处理
        //在数据行范围内为部门列设置部门列表下拉框
        String[] departmentArray=departmentNames.toArray(new String[departmentNames.size()]);
        String[] teacherArray=teacherNames.toArray(new String[teacherNames.size()]);
        for(int rowIndex=1;rowIndex<=rows.size();rowIndex++){
            writer.addSelect(2,rowIndex,departmentArray);
            writer.addSelect(3,rowIndex,teacherArray);
        }
        if(isTemplate){//如果是模板，将第一行样式标为红色，作为示例。必须放在数据都添加后设置才有用。
            // 为第一个单元格赋值，因为采用bean来传值的话，第一个单元格为Long类型，无法进行字符串复制。因此这里手动复制
            writer.writeCellValue(0,1,"示例：");
            //将原有单元格样式基础上将字体颜色修改为红色（注意看函数说明，这里会保留原有样式）
            CellStyle cellStyle= MyHutoolCustomExcelUtil.createRedCellStyle(writer, HorizontalAlignment.CENTER);
            //设置第一行包含有数据的样式为红色字体样式
            writer.setRowStyleIfHasData(1,cellStyle);
        }
    }

    /**
     *输出教师sheet
     * @param writer
     */
    private void writeExportTeacherSheet(ExcelWriter writer){
        //自定义需要读取或写出的Sheet，如果给定的sheet不存在，创建之。
        writer.setSheet("教师表（参考）");
        //将字体恢复为原有样式
        //CellStyle cellStyle= MyHutoolCustomExcelUtil.createNormalCellStyle(writer,HorizontalAlignment.CENTER);
        //必须要清掉上一个表设置的HeaderAlias，否则会混用
        writer.clearHeaderAlias();
        writer.addHeaderAlias("id","教师id");
        writer.addHeaderAlias("name","教师姓名");
        //设置角色集合
        List<SchoolTeacher> roles=schoolTeacherMapper.findAll(null);//查找所有角色
        // 默认的，未添加alias的属性也会写出，如果想只写出加了别名的字段，可以调用此方法排除之
        writer.setOnlyAlias(true);
        // 合并单元格后的标题行，使用默认标题样式
        writer.merge(writer.getHeaderAlias().size()-1, "教师列表");
        // 一次性写出内容，使用默认样式，强制输出标题
        writer.write(roles, true);
    }

    /**
     *输出部门sheet
     * @param writer
     */
    private void writeExportDepartmentSheet(ExcelWriter writer){
        //自定义需要读取或写出的Sheet，如果给定的sheet不存在，创建之。
        writer.setSheet("部门表（参考）");
        //将字体恢复为原有样式
        //CellStyle cellStyle= MyHutoolCustomExcelUtil.createNormalCellStyle(writer,HorizontalAlignment.CENTER);
        //必须要清掉上一个表设置的HeaderAlias，否则会混用
        writer.clearHeaderAlias();
        writer.addHeaderAlias("id","部门编号");
        writer.addHeaderAlias("name","部门名称");
        //设置角色集合
        List<SchoolDepartment> departments=schoolDepartmentMapper.findAll(null);//查找所有部门
        // 默认的，未添加alias的属性也会写出，如果想只写出加了别名的字段，可以调用此方法排除之
        writer.setOnlyAlias(true);
        // 合并单元格后的标题行，使用默认标题样式
        writer.merge(writer.getHeaderAlias().size()-1, "部门列表");
        // 一次性写出内容，使用默认样式，强制输出标题
        writer.write(departments, true);
    }

/*    @Override
    public ExcelWriter vxv () {
        // 定义用户集合
        List<SysUser> rows=sysUserMapper.findAll(null);
        //List<SysUser> rows=new ArrayList<>();
        //通过工具类创建writer
        ExcelWriter writer = ExcelUtil.getWriter(true);
        //自定义账户对象对应的标题别名
        writer.addHeaderAlias("username","用户名");
        writer.addHeaderAlias("nickName","昵称");
        writer.addHeaderAlias("sex","性别");
        writer.addHeaderAlias("status","账户状态");
        writer.addHeaderAlias("createTime","创建时间");
        // 默认的，未添加alias的属性也会写出，如果想只写出加了别名的字段，可以调用此方法排除之
        writer.setOnlyAlias(true);
        // 一次性写出内容，使用默认样式，强制输出标题
        writer.write(rows, true);
        return writer;
    }*/

    @Override
    public ExcelImportResult addMajorGroupsFromExcel(InputStream inputStream, @NotNull(message = "请先登录") SysUser user) {
        ExcelImportResult result=new ExcelImportResult();
        if(sysUserService.isSyperUser(user.getId())){//如果是超级用户
            //读取账户信息
            List<SchoolMajorGroup> majorGroups=validateAndReadExcel(inputStream);
            //从账户信息中将需要批量插入和批量更新的记录进行归类
            List<SchoolMajorGroup> newMajorGroups=new ArrayList<>();//新插入的记录，为了保证插入顺序，并且User重写了equal方法（根据id判断相等），必须使用list
            Set<SchoolMajorGroup> oldMajorGroups=new HashSet<>();//需要更新的记录，因为无所谓顺序，所以用set集合

            //为其余属性进行处理
            //对角色进行处理
            //将要变更的账户角色信息进行处理
            List<SchoolMajorGroupTeacher> majorGroupTeachersOfAdd=new ArrayList<>();//定义要批量添加的专业群群主关系
            List<SchoolMajorGroupTeacher>  majorGroupTeachersOfDelete=new ArrayList<>();//定义要批量移除的专业群群主关系
            //获取所有的角色,放在这里是为了提升性能
            List<SchoolTeacher> rolesOfAll=schoolTeacherMapper.findAll(null);
            for(SchoolMajorGroup majorGroupOfEach:majorGroups){
                if(majorGroupOfEach.getId()!=null){//如果需要更新的记录
                    oldMajorGroups.add(majorGroupOfEach);
                    result.setUpdateNumber(result.getUpdateNumber()+1);
                    //批量变更角色
                    //将前端传递过来的集合转换为set集合,顺便去重
                    Set<Long> teacherIdsSet = new HashSet<Long>(Arrays.asList(majorGroupOfEach.getTeacherIds()));
                    //获取原来的角色
                    List<SchoolTeacher> rolesOrigin=schoolMajorGroupTeacherMapper.findAllTeacherByMajorGroupId(majorGroupOfEach.getId());
                    //处理账户和角色的关系
                    for(SchoolTeacher teacher:rolesOfAll){
                        if(teacherIdsSet.contains(teacher.getId())){//如果本次使用了该角色
                            if(!rolesOrigin.contains(teacher)){//如果该角色原来不存在
                                //添加该角色关系
                                majorGroupTeachersOfAdd.add(new SchoolMajorGroupTeacher(majorGroupOfEach,new SchoolTeacher(teacher.getId())));
                            }
                        }else{//如果没有勾选该角色
                            if(rolesOrigin.contains(teacher)) {//如果该角色原来存在
                                //需要移除该的角色关系
                                majorGroupTeachersOfDelete.add(new SchoolMajorGroupTeacher(majorGroupOfEach,new SchoolTeacher(teacher.getId())));
                            }
                        }
                    }
                }else{
                    //设置初始排序为100
//                    majorGroupOfEach.setSort(100);
                    newMajorGroups.add(majorGroupOfEach);
                    result.setInsertNumber(result.getInsertNumber()+1);
                }
            }
            //批量插入记录
            schoolMajorGroupMapper.saveAllIn(newMajorGroups);
            //批量编辑记录
            schoolMajorGroupMapper.updateAllIn(oldMajorGroups);
            //对新角色进行角色处理，放在这里的原因是此时已经完成数据的添加，获取到了新插入记录的主键，才能进行关系赋予。
            for(SchoolMajorGroup majorGroupOfEach:newMajorGroups){
                for(Long teacherId:majorGroupOfEach.getTeacherIds()){//遍历要插入的新角色
                    SchoolMajorGroupTeacher schoolMajorGroupTeacher=new SchoolMajorGroupTeacher();
                    schoolMajorGroupTeacher.setSchoolMajorGroup(majorGroupOfEach);
                    schoolMajorGroupTeacher.setSchoolTeacher(new SchoolTeacher(teacherId));
                    majorGroupTeachersOfAdd.add(schoolMajorGroupTeacher);
                }
            }
//            //批量删除账户角色关系
            schoolMajorGroupTeacherMapper.deleteAllIn(majorGroupTeachersOfDelete);
//            //批量添加账户角色关系
            schoolMajorGroupTeacherMapper.saveAllIn(majorGroupTeachersOfAdd);
        }else{
            throw new AccessDeniedException("只有超级用户才能导入");
        }
        return result;
    }

    /**
     * 验证表中的字段并返回用户集合
     * 说明：用户创建时间、最后编辑时间不导入
     * @param inputStream
     */
    public List<SchoolMajorGroup> validateAndReadExcel(InputStream inputStream){
        //创建专业群对象集合
        List<SchoolMajorGroup> schoolMajorGroups=new ArrayList<>();
        //定义异常集合，用于返回具体的单元格错误异常信息
        List<ExcelExceptionMessage> excelExceptions=new ArrayList<ExcelExceptionMessage>();
        //获取工作簿对象
        ExcelReader excelReader = ExcelUtil.getReader(inputStream);
        //ExcelReader excelReader = ExcelUtil.getReader(inputStream,"账户列表");
        //获取所有工作表对象
        List<Sheet> sheets=excelReader.getSheets();
        boolean containsSheet=false;//是否包含指定sheet
        for(Sheet sheet:sheets){//遍历所有工作表
            if(sheet.getSheetName().equals(sheetName)){// 如果sheet名为指定的名称
                containsSheet=true;
                //根据该工作表重新创建一个ExcelReader对象
                excelReader=new ExcelReader(sheet);
                //首先判断表中的账户名是否存在重复信息
                if(MyTableUtil.validateRepeatColumn(excelReader.readColumn(1,1, excelReader.getRowCount()))){
                    throw new MyServiceException("导入失败：表格中的专业群名称存在重复字段");
                }
                //首先判断表中的网名是否存在重复信息
                if(MyTableUtil.validateRepeatColumn(excelReader.readColumn(2,1, excelReader.getRowCount()))){
                    throw new MyServiceException("导入失败：表格中的专业群名称存在重复字段");
                }
                //准备录入数据中要多次查找数据库的数据，避免后面遍历时重复查找，提升性能
                List<SchoolTeacher> teachers=schoolTeacherMapper.findAll(null);//获取数据库所有角色
                List<SchoolDepartment> departments=schoolDepartmentMapper.findAll(null);
                //获取set集合，因为是LinkedHashMap集合，因此转换过来的是有序的set集合
                Collection<String> valueSet=SCHOOLMAJORGROUPBEAN_MAP.values();
                //转为list集合,用于在后面能够根据键值获取所在的列索引（避免直接操作列索引导致的灵活性不足）
                List<String> keyList=new ArrayList<String>(valueSet);
                //读取第二行到最后一行数据
                //List<List<Object>> rows = excelReader.read(1, excelReader.getRowCount());
                List<Map<String,Object>> rows = excelReader.read(0,1, excelReader.getRowCount());
                //遍历每行的数据
                for(int rowIndex=0;rowIndex<rows.size();rowIndex++){
                    SchoolMajorGroup schoolMajorGroup=new SchoolMajorGroup();
                    Map<String,Object> row=rows.get(rowIndex);//获取当前行的数据
                    //第1列：专业群ID。如果id为空，表示该账户是要插入的账户；否则则是要更新相关信息
                    String majorGroupIdString=String.valueOf(row.get("专业群编号"));
                    //如果id存在则赋值
                    if(StringUtils.hasLength(majorGroupIdString)){
                        try {
                            schoolMajorGroup.setId(Integer.valueOf(majorGroupIdString));
                            //验证id是否在数据库存在，屏蔽无效id。这里用count，提升性能
                            SchoolMajorGroupQuery schoolMajorGroupQuery=new SchoolMajorGroupQuery();
                            schoolMajorGroupQuery.setId(schoolMajorGroup.getId());
                            if(schoolMajorGroupMapper.count(schoolMajorGroupQuery)==0){
                                excelExceptions.add(new ExcelExceptionMessage(sheet.getSheetName(),rowIndex+1,keyList.indexOf("专业群编号"),majorGroupIdString,"专业群主键在系统中不存在"));
                            }
                        } catch (NumberFormatException e) {
                            excelExceptions.add(new ExcelExceptionMessage(sheet.getSheetName(),rowIndex+1,keyList.indexOf("专业群编号"),majorGroupIdString,"专业群主键必须为整数"));
                        }
                    }
                    //第2列：专业群名称
                    String name=String.valueOf(row.get("专业群名称"));
                    //如果账户名存在则赋值
                    if(StringUtils.hasLength(name)){
                        schoolMajorGroup.setName(name);
                        if(schoolMajorGroup.getId()!=null){//如果不存在说明是要编辑，则要判定是否重名
                            if(schoolMajorGroupMapper.countByUsernameAndIdNot(name,schoolMajorGroup.getId())>0){//判断数据库中的账户是否重名
                                excelExceptions.add(new ExcelExceptionMessage(sheet.getSheetName(),rowIndex+1,keyList.indexOf("专业群名称"),name,"专业群名称在系统中重名"));
                            }
                        }else{//如果是要插入账户
                            if(schoolMajorGroupMapper.countByName(name)>0){//判断数据库中的账户是否重名
                                excelExceptions.add(new ExcelExceptionMessage(sheet.getSheetName(),rowIndex+1,keyList.indexOf("专业群名称"),name,"专业群名称在系统中重名"));
                            }
                        }
                    }else{
                        excelExceptions.add(new ExcelExceptionMessage(sheet.getSheetName(),rowIndex+1,keyList.indexOf("专业群名称"),name,"专业群名称不能为空"));
                    }
                    //第3列：部门
                    //部门名称
                    String departmentName=String.valueOf(row.get("部门名称"));
                    if(StringUtils.hasLength(departmentName)){
                        boolean exist=false;//默认该部门不存在
                        for(SchoolDepartment schoolDepartment:departments){
                            if(schoolDepartment.getName().equals(departmentName)){
                                exist=true;
                                schoolMajorGroup.setSchoolDepartment(schoolDepartment);
                                break;
                            }
                        }
                        if(!exist){
                            excelExceptions.add(new ExcelExceptionMessage(sheet.getSheetName(),rowIndex+1,keyList.indexOf("部门名称"),departmentName,departmentName+"在系统中不存在"));
                        }
                    }else{
                        excelExceptions.add(new ExcelExceptionMessage(sheet.getSheetName(),rowIndex+1,keyList.indexOf("部门名称"),departmentName,"必须选择部门"));
                    }
                    //第4列：群主集合
                    String teacherNames=String.valueOf(row.get("群主"));
                    if(StringUtils.hasLength(teacherNames)){
                        //将群主进行拆分
                        String[] teacherNameArray=teacherNames.split("\\|");
                        List<Long> groupTeacherIds=new ArrayList<>();
                        for(String teacherName:teacherNameArray) {
                            boolean existsTeacher = false;//默认该角色不存在
                            for (SchoolTeacher schoolTeacher:teachers) {
                                if (schoolTeacher.getName().equals(teacherName)) {
                                    existsTeacher = true;
                                    groupTeacherIds.add(schoolTeacher.getId());
                                    break;
                                }
                            }
                            if (!existsTeacher) {
                                excelExceptions.add(new ExcelExceptionMessage(sheet.getSheetName(), rowIndex + 1, keyList.indexOf("群主"), teacherNames, teacherName + "群主在系统中不存在"));
                            }
                        }
                        schoolMajorGroup.setTeacherIds(groupTeacherIds.toArray(new Long[groupTeacherIds.size()]));
                    }else {
                        excelExceptions.add(new ExcelExceptionMessage(sheet.getSheetName(),rowIndex+1,keyList.indexOf("群主"),teacherNames,"账户至少包含一个群主"));
                    }
                    //排序
                    String sortNumbers=String.valueOf(row.get("排序"));
                    //如果账户名存在则赋值
                    if(StringUtils.hasLength(sortNumbers)){
                        schoolMajorGroup.setSort(Integer.valueOf(sortNumbers));
                    }else{
                        excelExceptions.add(new ExcelExceptionMessage(sheet.getSheetName(),rowIndex+1,keyList.indexOf("排序"),sortNumbers,"排序不能为空"));
                    }
                    //教师数量
//                    schoolMajorGroup.setTeacherNumber(schoolMajorGroupTeacherMapper.countAllTeacherByMajorGroupId(schoolMajorGroup.getId()));


                    //将账户添加进集合
                    schoolMajorGroups.add(schoolMajorGroup);
                }
            }
        }
        if(!containsSheet){//如果指定表不存在
            throw new MyServiceException("导入失败：表格中必须有名称为"+sheetName+"的sheet");
        }
        if(excelExceptions.size()>0){//如果存在异常
            throw new MyExcelException(excelExceptions);
        }
        return schoolMajorGroups;
    }

}
